home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / daemons / nfs / nfs-serv.2be / nfs-serv / nfs-server-2.2beta16 / auth_clnt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-31  |  7.3 KB  |  294 lines

  1. /*
  2.  * auth_clnt.c    This module takes care of request authorization.
  3.  *
  4.  * Authors:    Don Becker, <becker@super.org>
  5.  *        Rick Sladkey, <jrs@world.std.com>
  6.  *        Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
  7.  *        Olaf Kirch, <okir@monad.swb.de>
  8.  *
  9.  *        This software maybe be used for any purpose provided
  10.  *        the above copyright notice is retained.  It is supplied
  11.  *        as is, with no warranty expressed or implied.
  12.  */
  13.  
  14.  
  15. #include "nfsd.h"
  16. #include "fakefsuid.h"
  17.  
  18. #ifndef svc_getcaller
  19. #define svc_getcaller(x) ((struct sockaddr_in *) &(x)->xp_rtaddr.buf)
  20. #endif
  21.  
  22.  
  23. #if defined(HAVE_SETFSUID) || defined(MAYBE_HAVE_SETFSUID)
  24. static _PRO(void setfsids, (uid_t, gid_t, gid_t *, int));
  25. #endif
  26. #ifndef HAVE_SETFSUID
  27. static _PRO(void seteids,  (uid_t, gid_t, gid_t *, int));
  28. #endif
  29.  
  30. uid_t        auth_uid = 0;        /* Current effective user ids */
  31. gid_t        auth_gid = 0;
  32. GETGROUPS_T    auth_gids[NGRPS];    /* Current supplementary gids */
  33. int        auth_gidlen = -1;
  34. uid_t        cred_uid;
  35. gid_t        cred_gid;
  36. gid_t        *cred_gids;
  37. int        cred_len;
  38.  
  39.  
  40. nfs_client *auth_clnt(rqstp)
  41. struct svc_req *rqstp;
  42. {
  43.     nfs_client    *cp = NULL;
  44.     struct in_addr addr = svc_getcaller(rqstp->rq_xprt)->sin_addr;
  45.  
  46.     /* Check if this is a known host, and if it's allowed to mount this */
  47.     if ((cp = auth_known_clientbyaddr(addr)) != NULL) {
  48.         return cp;
  49.     }
  50.  
  51.     /* No, it's not. Check against list of unknown hosts */
  52.     if ((cp = auth_unknown_clientbyaddr(addr)) != NULL) {
  53.         return cp;
  54.     }
  55.  
  56.     /* We don't know you */
  57.     if (trace_spoof) {    
  58.         dprintf(L_ERROR, "Access by unknown NFS client %s.\n",
  59.             inet_ntoa(addr));
  60.     }
  61.  
  62.     return (NULL);
  63. }
  64.  
  65. nfs_mount *auth_path(cp, rqstp, path)
  66. nfs_client *cp;
  67. struct svc_req *rqstp;
  68. char *path;
  69. {
  70.     nfs_mount    *mp;
  71.  
  72.     /* Check if the specified client is permitted to access this */
  73.     if ((mp = auth_match_mount(cp, path)) == NULL) {
  74.         if (cp->flags != 0 || trace_spoof) {
  75.             dprintf(L_ERROR, "NFS client %s tried to access %s\n",
  76.                 cp->clnt_name, path);
  77.         }
  78.         return NULL;
  79.     }
  80.  
  81.     /* Check request originated on a privileged port. */
  82.     if (!allow_non_root && mp->o.secure_port &&
  83.         ntohs(svc_getcaller(rqstp->rq_xprt)->sin_port) >= IPPORT_RESERVED) {
  84.         dprintf(L_ERROR,
  85.             "NFS request from %s originated on insecure port, %s\n",
  86.             cp->clnt_name,
  87.             "psychoanalysis suggested");
  88.         return (NULL);
  89.     }
  90.  
  91.     if (logging_enabled(D_AUTH)) {
  92.         dprintf(D_AUTH, "auth_path(%s): mount point %s, (%s%s%s%s%s)\n",
  93.             path, mp->path,
  94.             mp->o.all_squash? "all_squash " : (
  95.              mp->o.root_squash? "root_squash " : ""),
  96.             (mp->o.uidmap == map_daemon)? "uidmap " : "",
  97.             mp->o.secure_port? "secure " : "insecure ",
  98.             mp->o.link_relative? "linkrel " : "",
  99.             mp->o.read_only? "ro" : "rw");
  100.     }
  101.  
  102.     return mp;
  103. }
  104.  
  105. void auth_user(mp, rqstp)
  106. nfs_mount *mp;
  107. struct svc_req *rqstp;
  108. {
  109.     uid_t        cuid;
  110.     gid_t        cgid;
  111.     GETGROUPS_T    cgids[NGRPS];
  112.     int        squash = mp->o.all_squash;
  113.     int        clen, i;
  114.  
  115.     if (rqstp->rq_cred.oa_flavor == AUTH_UNIX) {
  116.         struct authunix_parms *unix_cred;
  117.  
  118.         unix_cred = (struct authunix_parms *) rqstp->rq_clntcred;
  119.         cred_uid  = unix_cred->aup_uid;
  120.         cred_gid  = unix_cred->aup_gid;
  121.         cred_len  = unix_cred->aup_len;
  122.         cred_gids = unix_cred->aup_gids;
  123.     } else {
  124.         /* We will want to support AUTH_DES/AUTH_KRB one day,
  125.          * but for now we treat all other authentication flavor
  126.          * as AUTH_NULL.
  127.          */
  128.         squash = 1;
  129.         cred_uid  = mp->o.nobody_uid;
  130.         cred_gid  = mp->o.nobody_gid;
  131.         cred_gids = NULL;
  132.         cred_len  = 0;
  133.     }
  134.  
  135.     if (cred_len > NGRPS)
  136.         cred_len = NGRPS;
  137.  
  138.     if (!squash) {
  139.         /* Do the uid/gid mapping here.
  140.          * Note that we check cred_uid (which is a short), not
  141.          * unix_cred->aup_uid to avoid the uid masking bug.
  142.          */
  143.         cuid = luid(cred_uid, mp, rqstp);
  144.         cgid = lgid(cred_gid, mp, rqstp);
  145.         clen = cred_len;
  146.         for (i = 0; i < cred_len; i++)
  147.             cgids[i] = lgid(cred_gids[i], mp, rqstp);
  148.     } else {
  149.         cuid = mp->o.nobody_uid;
  150.         cgid = mp->o.nobody_gid;
  151.         /* Construct a list of one gid. */
  152.         cgids[0] = cgid;
  153.         clen = 1;
  154.     }
  155.  
  156.     /* This code is a little awkward because setfsuid has been present
  157.      * in the Linux kernel for quite some time but not in libc.
  158.      * The startup code tests for the setfsuid syscall and sets
  159.      * have_setfsuid accordingly.
  160.      */
  161. #if defined(HAVE_SETFSUID)
  162.     setfsids(cuid, cgid, cgids, clen);
  163. #else
  164. #if defined(MAYBE_HAVE_SETFSUID)
  165.     if (have_setfsuid)
  166.         setfsids(cuid, cgid, cgids, clen);
  167.     else
  168. #endif
  169.         seteids(cuid, cgid, cgids, clen);
  170. #endif
  171. }
  172.  
  173. /*
  174.  * The following functions deal with setting the client's uid/gid.
  175.  */
  176. void auth_override_uid(uid)
  177. uid_t uid;
  178. {
  179. #if defined(HAVE_SETFSUID)
  180.     setfsuid(uid);
  181. #else
  182. #if defined(MAYBE_HAVE_SETFSUID)
  183.     if (have_setfsuid)
  184.         setfsuid(uid);
  185.     else
  186. #endif
  187.         seteuid(uid);
  188. #endif
  189. }
  190.  
  191. #if defined(HAVE_SETFSUID) || defined(MAYBE_HAVE_SETFSUID)
  192. static void setfsids(cred_uid, cred_gid, cred_gids, cred_len)
  193. uid_t cred_uid;
  194. gid_t cred_gid, *cred_gids;
  195. int cred_len;
  196. {
  197.     /* First, set the user ID. */
  198.     if (auth_uid != cred_uid) {
  199.         if (setfsuid(cred_uid) < 0)
  200.             dprintf(L_ERROR, "Unable to setfsuid %d: %s\n",
  201.                 cred_uid, strerror(errno));
  202.         else
  203.             auth_uid = cred_uid;
  204.     }
  205.  
  206.     /* Next, the group ID. */
  207.     if (auth_gid != cred_gid) {
  208.         if (setfsgid(cred_gid) < 0)
  209.             dprintf(L_ERROR, "Unable to setfsgid %d: %s\n",
  210.                 cred_gid, strerror(errno));
  211.         else
  212.             auth_gid = cred_gid;
  213.     }
  214.  
  215. #ifdef HAVE_SETGROUPS
  216.     /* Finally, set the supplementary group IDs if possible. */
  217.     if (cred_len < 0 || cred_len > NGRPS)
  218.         dprintf(L_ERROR, "Negative or huge cred_len: %d\n", cred_len);
  219.     else if (cred_len != auth_gidlen
  220.         || memcmp(cred_gids, auth_gids, auth_gidlen*sizeof(gid_t))) {
  221.         if (setgroups(cred_len, cred_gids) < 0)
  222.             dprintf(L_ERROR, "Unable to setgroups: %s\n",
  223.                 strerror(errno));
  224.         else {
  225.             memcpy(auth_gids, cred_gids, cred_len*sizeof(gid_t));
  226.             auth_gidlen = cred_len;
  227.         }
  228.     }
  229. #endif /* HAVE_SETGROUPS */
  230.  
  231. }
  232. #endif
  233.  
  234. #if !defined(HAVE_SETFSUID)
  235. static void seteids(cred_uid, cred_gid, cred_gids, cred_len)
  236. uid_t cred_uid;
  237. gid_t cred_gid, *cred_gids;
  238. int cred_len;
  239. {
  240.     /* To set any IDs we first need to be root. What a pain. */
  241.  
  242.     /* First set the group ID. */
  243.     if (auth_gid != cred_gid) {
  244.         if (auth_uid != ROOT_UID) {
  245.             if (seteuid(ROOT_UID) < 0)
  246.                 dprintf(L_ERROR, "Unable to seteuid(%d): %s\n",
  247.                     ROOT_UID, strerror(errno));
  248.             else
  249.                 auth_uid = ROOT_UID;
  250.         }
  251.         if (setegid(cred_gid) < 0)
  252.             dprintf(L_ERROR, "Unable to setegid(%d): %s\n",
  253.                 cred_gid, strerror(errno));
  254.         else
  255.             auth_gid = cred_gid;
  256.     }
  257.  
  258. #ifdef HAVE_SETGROUPS
  259.     /* Next set the supplementary group IDs if possible. */
  260.     if (cred_len < 0 || cred_len > NGRPS)
  261.         dprintf(L_ERROR, "Negative or huge cred_len: %d\n", cred_len);
  262.     else if (cred_len != auth_gidlen
  263.         || memcmp(cred_gids, auth_gids, auth_gidlen*sizeof(gid_t))) {
  264.         if (auth_uid != ROOT_UID) {
  265.             if (seteuid(ROOT_UID) < 0)
  266.                 dprintf(L_ERROR, "Unable to seteuid(%d): %s\n",
  267.                     ROOT_UID, strerror(errno));
  268.             else
  269.                 auth_uid = ROOT_UID;
  270.         }
  271.         if (setgroups(cred_len, cred_gids) < 0)
  272.             dprintf(L_ERROR, "Unable to setgroups: %s\n",
  273.                 strerror(errno));
  274.         else {
  275.             memcpy(auth_gids, cred_gids, cred_len*sizeof(gid_t));
  276.             auth_gidlen = cred_len;
  277.         }
  278.     }
  279. #endif /* HAVE_SETGROUPS */
  280.  
  281.     /* Finally, set the user ID. */
  282.     if (auth_uid != cred_uid) {
  283.         if (auth_uid != ROOT_UID && seteuid(ROOT_UID) < 0)
  284.             dprintf(L_ERROR, "Unable to seteuid(%d): %s\n", 
  285.                 ROOT_UID, strerror(errno));
  286.         if (seteuid(cred_uid) < 0)
  287.             dprintf(L_ERROR, "Unable to seteuid(%d): %s\n",
  288.                 cred_uid, strerror(errno));
  289.         else
  290.             auth_uid = cred_uid;
  291.     }
  292. }
  293. #endif
  294.